package com.client
{
	import com.client.event.VerEvent;
	
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.TextEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	
	/**
	 * 公共库加载器
	 * @author Tide
	 */
	public class DLLLoader extends EventDispatcher
	{
		private var _stream:URLStream;
		private var _loader:Loader;
		private var _dllList:Array;
		private var _isRelease:Boolean = false;
		private var _ver:String;
		
		public function DLLLoader(ver:String)
		{
			_ver = ver;
			initLoader();
		}
		
		/**
		 * init URLStream and URLLoader
		 */
		private function initLoader():void
		{
			_stream = new URLStream();
			_stream.addEventListener(Event.OPEN,onOpen);
			_stream.addEventListener(Event.COMPLETE,onComplete);
			_stream.addEventListener(ProgressEvent.PROGRESS,onProgressHandler);
			_stream.addEventListener(IOErrorEvent.IO_ERROR,onError);
			
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaderOver);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
			
			
		}
		
		/**
		 * 开始加载
		 * @param xmlData
		 * @param verMap
		 * @param isRealease
		 */
		public function doLoad(xmlData:XML,verMap:Object,isRelease:Boolean=false):void
		{
			_dllList = [];
			_isRelease = isRelease;
			var xmlList:XMLList = xmlData.elements();
			for each(var xml:XML in xmlList)
			{
				var info:DLLInfo = new DLLInfo();
				info.name = xml.@name;
				info.path = xml.@path;
				/*var obj:Object = verMap[info.path];
				info.size = obj.s;
				info.ver = obj.v;
				if(info.ver == null)
					info.ver = _ver;*/
				_dllList.push(info);
			}
			beginLoad();
		}
		
		private function beginLoad():void
		{
			if(_dllList.length > 0)
			{
				var info:DLLInfo = _dllList[0];
				_stream.load(new URLRequest(info.path + "?" + info.ver + SO.getSOver()));trace("正在加载："+info.path);
			}
			else
			{
				_stream.removeEventListener(Event.OPEN,onOpen);
				_stream.removeEventListener(Event.COMPLETE,onComplete);
				_stream.removeEventListener(ProgressEvent.PROGRESS,onProgressHandler);
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onLoaderOver);
				_stream = null;
				_loader = null;
				dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		private function onOpen(event:Event):void
		{
			var info:DLLInfo = _dllList[0];
			dispatchEvent(new TextEvent(Event.OPEN, false, false, "加载" + info.name));
		}
		
		private function onProgressHandler(event:ProgressEvent):void
		{
			dispatchEvent(event);
		}
		
		private function onComplete(event:Event):void
		{
			var info:DLLInfo = _dllList[0];
			if(_isRelease && _stream.bytesAvailable != info.size)
			{
				_stream.removeEventListener(Event.OPEN,onOpen);
				_stream.removeEventListener(Event.COMPLETE,onComplete);
				_stream.removeEventListener(ProgressEvent.PROGRESS,onProgressHandler);
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onLoaderOver);
				_stream = null;
				_loader = null;
				dispatchEvent(new VerEvent(VerEvent.SIZE_ERROR));
			}
			
			var byteArray:ByteArray = new ByteArray();
			if(_isRelease)
			{
				//flash.system.trace(_stream);
			}
			_stream.readBytes(byteArray);
			if(_isRelease)
			{
				byteArray.uncompress();
			}
			_stream.close();
			var loaderContext:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);
			loaderContext.allowCodeImport = true;
			_loader.loadBytes(byteArray,loaderContext);
		}
		
		private function onError(event:IOErrorEvent):void
		{
			trace(event.text);
		}
		
		private function onLoaderOver(event:Event):void
		{
			_dllList.shift();
			beginLoad();
		}
	}
}
class DLLInfo
{
	public var name:String;
	public var ver:String;
	public var path:String;
	public var size:uint;
}